use gloo::net::http::Request;

use shared::{ServerInfo, NetemProfile};

// GET /api/server_info
pub async fn get_server_info() -> Result<ServerInfo, String> {
    let resp = Request::get("/api/server_info")
        .send()
        .await
        .map_err(|err| err.to_string())?;
    if !resp.ok() {
        Err(format!(
            "Error fetching data {} ({})",
            resp.status(),
            resp.status_text()
        ))
    } else {
        resp.json::<ServerInfo>()
            .await
            .map_err(|err| err.to_string())
    }
}

// GET /api/profiles
pub async fn get_profiles() -> Result<Vec<NetemProfile>, String> {
    let resp = Request::get("/api/profiles")
        .send()
        .await
        .map_err(|err| err.to_string())?;
    if !resp.ok() {
        Err(format!(
            "Error fetching data {} ({})",
            resp.status(),
            resp.status_text()
        ))
    } else {
        resp.json::<Vec<NetemProfile>>()
            .await
            .map_err(|err| err.to_string())
    }
}

// POST /api/profiles
pub async fn create_profile(profile: NetemProfile) -> Result<NetemProfile, String> {
    let resp = Request::post("/api/profiles")
        .json(&profile)
        .map_err(|err| err.to_string())?
        .send()
        .await
        .map_err(|err| err.to_string())?;
    if !resp.ok() {
        Err(format!(
            "Error fetching data {} ({})",
            resp.status(),
            resp.status_text()
        ))
    } else {
        resp.json::<NetemProfile>()
            .await
            .map_err(|err| err.to_string())
    }
}

// GET /api/profiles/:id
pub async fn get_profile(id: uuid::Uuid) -> Result<NetemProfile, String> {
    let resp = Request::get(&format!("/api/profiles/{}", id))
        .send()
        .await
        .map_err(|err| err.to_string())?;
    if !resp.ok() {
        Err(format!(
            "Error fetching data {} ({})",
            resp.status(),
            resp.status_text()
        ))
    } else {
        resp.json::<NetemProfile>()
            .await
            .map_err(|err| err.to_string())
    }
}

// PATCH /api/profiles/:id
pub async fn update_profile(profile: NetemProfile) -> Result<NetemProfile, String> {
    let resp = Request::patch(&format!("/api/profiles/{}", profile.id))
        .json(&profile)
        .map_err(|err| err.to_string())?
        .send()
        .await
        .map_err(|err| err.to_string())?;
    if !resp.ok() {
        Err(format!(
            "Error fetching data {} ({})",
            resp.status(),
            resp.status_text()
        ))
    } else {
        resp.json::<NetemProfile>()
            .await
            .map_err(|err| err.to_string())
    }
}

// PATCH /api/profiles/:id
pub async fn delete_profile(profile: NetemProfile) -> Result<(), String> {
    let resp = Request::delete(&format!("/api/profiles/{}", profile.id))
        .send()
        .await
        .map_err(|err| err.to_string())?;
    if !resp.ok() {
        Err(format!(
            "Error fetching data {} ({})",
            resp.status(),
            resp.status_text()
        ))
    } else {
        Ok(())
    }
}
